﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Web;
using System.Web.Caching;
using System.Collections;

namespace SF.Base.Core {
	public class CH {
		public struct Keys {
			public const string dict_tb_new_word_cache_key = "DICT_TB_NEW_WORD_CACHE_KEY";
			public const string dict_tb_new_sort_cache_key = "DICT_TB_NEW_SORT_CACHE_KEY";
			public const string dict_tb_new_vocabulary_word_cache_key = "DICT_TB_NEW_VOCABULARY_WORD_CACHE_KEY";
			public const string dict_tb_new_vocabulary_cache_key = "DICT_TB_NEW_VOCABULARY_CACHE_KEY";

			public const string dict_ob_vocabulary_word_list_cache_key = "DICT_OB_VOCABULARY_WORD_LIST_CACHE_KEY";

			public const string dict_str_json_ob_vocabulary_word_list = "DICT_STR_JSON_OB_VOCABULARY_WORD_LIST";

			public const string sf_t_system_entity = "SF_T_SYSTEM_ENTITY";

			public const string TAXONOMYENTITY = "TAXONOMYENTITY";

			public const string DT_T_VOCABULARY = "DT_T_VOCABULARY";

			public const string DT_T_VOCABULARYLIST = "DT_T_VOCABULARYLIST";
			public const string DT_T_VOCABULARYDICTLIST = "DT_T_VOCABULARYDICTLIST";
			public const string DT_O_LISTINDEXCOUNT = "DT_O_LISTINDEXCOUNT";
			public const string STATION = "STATION";
			public const string DICT = "DICT";
		}

		public struct Minutes {
			public const double m120 = 120;
		}

		public static double DEFAULTMINUTES = Minutes.m120;

		public static T GetAndSetCache<T>(string cacheKey, Func<T> func) {
			return GetAndSetCache(cacheKey, Minutes.m120, func);
		}

		public static T GetAndSetCache<T>(string cacheKey, double minutes, Func<T> func) {
			T o = CH.GetCache<T>(cacheKey);
			if (o == null || o.Equals(default(T))) {
				try {
					o = func();
					CH.SetCache<T>(cacheKey, o, minutes);
				}
				catch (Exception) {
				}
			}

			return o;
		}

		public static T GetAndSetCache<T, TP>(string cacheKey, double minutes, Func<TP, T> func, TP param) {
			T o = CH.GetCache<T>(cacheKey);
			if (o == null || o.Equals(default(T))) {
				try {
					o = func(param);
					CH.SetCache<T>(cacheKey, o, minutes);
				}
				catch (Exception) {
				}
			}

			return o;
		}

		/// <summary>
		/// 填充数据至服务器缓存
		/// </summary>
		/// <param name="key"></param>
		/// <param name="obj"></param>
		/// <param name="minutes"></param>
		/// <returns></returns>
		public static void SetCache<T>(string key, T obj, double minutes) {
			if (HttpContext.Current == null) {
				throw new InvalidOperationException("设置对象缓存失败, 无法获取HttpContext对象");
			}

			HttpContext.Current.Cache.Insert(key, obj, null, DateTime.UtcNow.AddMinutes(minutes), TimeSpan.Zero);
		}


		/// <summary>
		/// 从缓存获得List数据
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="key"></param>
		/// <returns>如果缓存项不存在,或者缓存项不是IList&lt;T&gt;的子类对象, 则返回null</returns>
		public static List<T> GetListCache<T>(string key) {
			if (HttpContext.Current == null) {
				throw new InvalidOperationException("读取缓存失败, 无法获取HttpContext对象");
			}

			List<T> list = null;
			if (HttpContext.Current.Cache[key] != null) {
				list = HttpContext.Current.Cache[key] as List<T>;
			}
			return list;
		}

		/// <summary>
		/// 从缓存获得List数据
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="key"></param>
		/// <returns>如果缓存项不存在,或者缓存项不是IList&lt;T&gt;的子类对象, 则返回null</returns>
		public static void SetListCache<T>(string key, List<T> obj) {
			if (HttpContext.Current == null) {
				throw new InvalidOperationException("设置对象缓存失败, 无法获取HttpContext对象");
			}

			HttpContext.Current.Cache.Insert(key, obj, null, DateTime.UtcNow.AddMinutes(DEFAULTMINUTES), TimeSpan.Zero);
		}

		/// <summary>
		/// 从缓存获得数据
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="key"></param>
		/// <returns>如果缓存项不存在,或者缓存项不是T的子类对象, 则返回T的默认值</returns>
		public static T GetCache<T>(string key) {
			if (HttpContext.Current == null) {
				throw new InvalidOperationException("读取缓存失败, 无法获取HttpContext对象");
			}

			T obj = default(T);
			if (HttpContext.Current.Cache[key] != null) {
				try {
					obj = (T)HttpContext.Current.Cache[key];
				}
				catch (InvalidCastException) {
					return obj;
				}
			}
			return obj;
		}

		/// <summary>
		/// 从Session获得会话值
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="key"></param>
		/// <returns>如果Session项不存在, 或者Session项不是T的子类对象, 则返回T的默认值</returns>
		public static T GetSessionValue<T>(string key) {
			if (HttpContext.Current == null) {
				throw new InvalidOperationException("读取Session失败, 无法获取HttpContext对象");
			}

			T obj = default(T);
			if (HttpContext.Current.Session[key] != null) {
				try {
					obj = (T)HttpContext.Current.Session[key];
				}
				catch (InvalidCastException) {
					return obj;
				}
			}
			return obj;
		}

		/// <summary>
		/// 针对每次请求,获得Item
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="key"></param>
		/// <returns>如果共享Item项不存在, 或者共享Item项不是T的子类对象, 则返回T的默认值</returns>
		public static T GetItem<T>(string key) {
			if (HttpContext.Current == null) {
				throw new InvalidOperationException("读取共享Item失败, 无法获取HttpContext对象");
			}

			T obj = default(T);
			if (HttpContext.Current.Items[key] != null) {
				try {
					obj = (T)HttpContext.Current.Items[key];
				}
				catch (InvalidCastException) {
					return obj;
				}
			}
			return obj;
		}



		/// <summary>
		/// 填充Item至Session
		/// </summary>
		/// <param name="key"></param>
		/// <param name="obj"></param>
		public static void SetSessionValue<T>(string key, T obj) {
			if (HttpContext.Current == null) {
				throw new InvalidOperationException("设置Session失败, 无法获取HttpContext对象");
			}
			HttpContext.Current.Session[key] = obj;
		}

		/// <summary>
		/// 填充Item至当前请求
		/// </summary>
		/// <param name="key"></param>
		/// <param name="obj"></param>
		public static void SetItemValue<T>(string key, T obj) {
			if (HttpContext.Current == null) {
				throw new InvalidOperationException("设置共享Items失败, 无法获取HttpContext对象");
			}
			HttpContext.Current.Items[key] = obj;
		}

		/// <summary>
		/// 移除对象缓存
		/// </summary>
		/// <param name="key"></param>
		public static void RemoveCache(string key) {
			if (HttpContext.Current == null) {
				throw new InvalidOperationException("删除对象缓存失败, 无法获取HttpContext对象");
			}

			if (HttpContext.Current.Cache[key] != null) {
				HttpContext.Current.Cache.Remove(key);
			}
		}

		/// <summary>
		/// 重置当前应用程序所有缓存
		/// </summary>
		/// <param name="key"></param>
		public static void ResetCache() {
			if (HttpContext.Current == null) {
				throw new InvalidOperationException("重置全部缓存失败, 无法获取HttpContext对象");
			}

			Cache globalCache = System.Web.HttpRuntime.Cache;
			if (globalCache == null) {
				throw new InvalidOperationException("重置全部缓存失败, 无法获取应用程序缓存对象");
			}

			IDictionaryEnumerator CacheEnum = globalCache.GetEnumerator();
			while (CacheEnum.MoveNext()) {
				globalCache.Remove(CacheEnum.Key.ToString());
			}
		}

		/// <summary>
		/// 模糊重置所有数据缓存
		/// </summary>
		public static void ResetCacheByPattern(string pattern) {
			if (HttpContext.Current == null) {
				throw new InvalidOperationException("重置全部缓存失败, 无法获取HttpContext对象");
			}

			Cache globalCache = System.Web.HttpRuntime.Cache;
			if (globalCache == null) {
				throw new InvalidOperationException("重置全部缓存失败, 无法获取应用程序缓存对象");
			}

			IDictionaryEnumerator CacheEnum = globalCache.GetEnumerator();
			while (CacheEnum.MoveNext()) {
				if (CacheEnum.Key.ToString().ToLower().IndexOf(pattern) > -1) {
					globalCache.Remove(CacheEnum.Key.ToString());
				}
			}
		}
	}
}
